content: /* ###
   * IP: GHIDRA
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package firmware.fmap;
  
  import ghidra.app.util.bin.BinaryReader;
  
  import java.io.IOException;
  
  /**
   * Parser for Flash Map (FMAP) layouts, as used by Chromium OS devices and coreboot.
   *
   * The flash layout is described by the flash area structures, which appear directly after the
   * flash map header. Note that the flash map header is not required to be at the start of the
   * firmware binary.
   *
   * <pre>
   *   Flash Map Header
   *   +----------+------+-------------------------+
   *   | Type     | Size | Description             |
   *   +----------+------+-------------------------+
   *   | char[8]  |    8 | Signature ("__FMAP__")  |
   *   | u8       |    1 | Major Version           |
   *   | u8       |    1 | Minor Version           |
   *   | u64      |    8 | Base Address            |
   *   | u32      |    4 | Size                    |
   *   | char[32] |   32 | Name of Firmware Binary |
   *   | u16      |    2 | Number of flash areas   |
   *   +----------+------+-------------------------+
   * </pre>
   *
   * The flash area structures immediately follow the flash map header. See FlashMapArea for a
   * description of the fields.
   */
  public class FlashMapHeader {
  	// Original header fields
  	private final String signature;
  	private final int majorVersion;
  	private final int minorVersion;
  	private final long baseAddress;
  	private final long size;
  	private final String name;
  	private final int numAreas;
  
  	private final FlashMapArea[] areas;
  
  	/**
  	 * Constructs a FlashMapHeader from a specified BinaryReader.
  	 *
  	 * @param reader the specified BinaryReader
  	 */
  	public FlashMapHeader(BinaryReader reader) throws IOException {
  		signature = reader.readNextAsciiString(FlashMapConstants.FMAP_SIGNATURE.length());
  		if (!signature.equals(FlashMapConstants.FMAP_SIGNATURE)) {
  			throw new IOException("Not a valid flash map");
  		}
  
  		// Read the header fields.
  		majorVersion = reader.readNextUnsignedByte();
  		minorVersion = reader.readNextUnsignedByte();
  		baseAddress = reader.readNextLong();
  		size = reader.readNextUnsignedInt();
  		name = reader.readNextAsciiString(FlashMapConstants.FMAP_NAME_LEN).trim();
  
  		// Read each flash area.
  		numAreas = reader.readNextUnsignedShort();
  		areas = new FlashMapArea[numAreas];
  		for (int i = 0; i < numAreas; i++) {
  			areas[i] = new FlashMapArea(reader);
  		}
  	}
  
  	/**
  	 * Returns an array of FlashMapAreas.
  	 *
  	 * @return an array of FlashMapAreas
  	 */
  	public FlashMapArea[] getAreas() {
  		return areas;
  	}
  
  	/**
  	 * Returns the base address for the current firmware binary.
  	 *
  	 * @return the base address for the current firmware binary
  	 */
  	public long getBaseAddress() {
  		return baseAddress;
  	}
  
  	/**
  	 * Returns the name of the current firmware binary.
  	 *
  	 * @return the name of the current firmware binary
  	 */
  	public String getName() {
  		return name;
  	}
  
  	/**
  	 * Returns the version string for the current firmware binary.
  	 *
  	 * @return the version string for the current firmware binary
  	 */
  	public String getVersion() {
  		return String.format("%d.%d", majorVersion, minorVersion);
  	}
  }
  