Search in sources :

Example 1 with UnsignedInteger

use of com.google.common.primitives.UnsignedInteger in project buck by facebook.

the class ObjectPathsAbsolutifier method processSymTabCommand.

private int processSymTabCommand(MachoMagicInfo magicInfo, SymTabCommand symTabCommand) throws IOException {
    UnsignedInteger originalStringTableSize = symTabCommand.getStrsize();
    HashMap<Path, Path> originalToUpdatedPathMap = new HashMap<>();
    // If an SO entry has a string ending in /, then the next symbol
    // is a continuation of this path.  That shouldn't be fixed.
    boolean lastEntryWasContinuation = false;
    for (int idx = 0; idx < symTabCommand.getNsyms().intValue(); idx++) {
        Nlist nlist = SymTabCommandUtils.getNlistAtIndex(buffer, symTabCommand, idx, magicInfo.is64Bit());
        final boolean stabIsSourceOrHeaderFile = nlist.getN_type().equals(Stab.N_SO) || nlist.getN_type().equals(Stab.N_SOL);
        final boolean stabIsObjectFile = nlist.getN_type().equals(Stab.N_OSO);
        if (!stabIsSourceOrHeaderFile && !stabIsObjectFile) {
            continue;
        }
        Preconditions.checkArgument(!SymTabCommandUtils.stringTableEntryIsNull(nlist), "Path to object file is `null` string, this is unexpected.");
        if (SymTabCommandUtils.stringTableEntryIsEmptyString(buffer, symTabCommand, nlist)) {
            continue;
        }
        boolean entryIsContinuation = lastEntryWasContinuation;
        lastEntryWasContinuation = SymTabCommandUtils.stringTableEntryEndsWithSlash(buffer, symTabCommand, nlist);
        if (entryIsContinuation) {
            // entry in the sequence would have been adjusted as needed.
            continue;
        }
        if (SymTabCommandUtils.stringTableEntryStartsWithSlash(buffer, symTabCommand, nlist) && !stabIsObjectFile) {
            // already absolute, skipping
            continue;
        }
        String stringPath = SymTabCommandUtils.getStringTableEntryForNlist(buffer, symTabCommand, nlist, nulTerminatedCharsetDecoder);
        Path absolutePath = getAbsolutePath(stringPath);
        // absolutePathString is the string that will be used as a value inside binary. It may be
        // different from absolutePath.toString() because the first one is absolute path to the
        // Mach O file, and the last one is absolute path for the loader to the object file.
        // Examples:
        //   absolute path to library is /path/to/lib.a
        //   absolutePathString to object file in library: /path/to/lib.a(somefile.o)
        //
        //   absolute path to a continuation part of the path: /path/to/folder
        //   absolutePathString to a continuation part of the path: /path/to/folder/
        //   (as the next symbol will contain continuation of this path, e.g. file.cpp)
        String absolutePathString;
        if (stabIsSourceOrHeaderFile) {
            // source and header files should not be unsanitized
            absolutePathString = absolutePath.toString();
        } else {
            // object files need to be unsanitized
            Path relativePath = getAbsolutePath(filesystem.getRootPath().toString()).relativize(absolutePath);
            Path unsanitizedAbsolutePath = getUnsanitizedAbsolutePath(relativePath);
            absolutePathString = unsanitizedAbsolutePath.toString();
            if (absolutePath.toFile().exists() && relativePath.startsWith(filesystem.getBuckPaths().getGenDir().toString())) {
                originalToUpdatedPathMap.put(absolutePath, unsanitizedAbsolutePath);
            } else {
                Optional<String> archiveEntryName = getArchiveEntryNameFromPath(absolutePath);
                if (archiveEntryName.isPresent()) {
                    Path sourceArchivePath = getArchivePathFromPath(absolutePath);
                    Path targetArchivePath = getArchivePathFromPath(unsanitizedAbsolutePath);
                    originalToUpdatedPathMap.put(sourceArchivePath, targetArchivePath);
                }
            }
        }
        if (lastEntryWasContinuation) {
            absolutePathString += "/";
        }
        symTabCommand = updateSymTabCommandByUpdatingNlistEntry(magicInfo, symTabCommand, nlist, absolutePath, absolutePathString);
    }
    unsanitizeObjectFiles(ImmutableMap.copyOf(originalToUpdatedPathMap));
    return symTabCommand.getStrsize().minus(originalStringTableSize).intValue();
}
Also used : Path(java.nio.file.Path) HashMap(java.util.HashMap) UnsignedInteger(com.google.common.primitives.UnsignedInteger)

Example 2 with UnsignedInteger

use of com.google.common.primitives.UnsignedInteger in project buck by facebook.

the class LoadCommandUtils method createLoadCommandFromBuffer.

/**
   * This is a kind of umbrella method that returns you LoadCommand object depending on the contents
   * of the given bytes array.
   * @param buffer Buffer which contains at least values for the LoadCommand fields,
   *               positioned at the first byte of the command (cmd field)
   * @return LoadCommandCommonFields that is suitable to handle the given bytes array.
   */
public static LoadCommand createLoadCommandFromBuffer(ByteBuffer buffer, NulTerminatedCharsetDecoder nulTerminatedCharsetDecoder) {
    int position = buffer.position();
    UnsignedInteger cmd = UnsignedInteger.fromIntBits(buffer.getInt());
    buffer.position(position);
    if (SegmentCommand.VALID_CMD_VALUES.contains(cmd)) {
        return SegmentCommandUtils.createFromBuffer(buffer, nulTerminatedCharsetDecoder);
    } else if (cmd.equals(SymTabCommand.LC_SYMTAB)) {
        return SymTabCommandUtils.createFromBuffer(buffer);
    } else if (cmd.equals(UUIDCommand.LC_UUID)) {
        return UUIDCommandUtils.createFromBuffer(buffer);
    } else if (LinkEditDataCommand.VALID_CMD_VALUES.contains(cmd)) {
        return LinkEditDataCommandUtils.createFromBuffer(buffer);
    } else {
        return UnknownCommandUtils.createFromBuffer(buffer);
    }
}
Also used : UnsignedInteger(com.google.common.primitives.UnsignedInteger)

Example 3 with UnsignedInteger

use of com.google.common.primitives.UnsignedInteger in project buck by facebook.

the class MachoHeaderUtils method createFromBuffer.

/**
   * Reads the Mach Header from the given buffer from current position.
   * @param buffer Buffer that holds the data of the mach header
   * @return MachoHeader for 32 or 64 bit Mach object.
   */
public static MachoHeader createFromBuffer(ByteBuffer buffer) {
    int position = buffer.position();
    UnsignedInteger magic = UnsignedInteger.fromIntBits(buffer.getInt());
    buffer.position(position);
    Preconditions.checkArgument(magic.equals(MachoHeader.MH_MAGIC) || magic.equals(MachoHeader.MH_MAGIC_64));
    if (magic.equals(MachoHeader.MH_MAGIC_64)) {
        return create64BitFromBuffer(buffer);
    } else {
        return create32BitFromBuffer(buffer);
    }
}
Also used : UnsignedInteger(com.google.common.primitives.UnsignedInteger)

Example 4 with UnsignedInteger

use of com.google.common.primitives.UnsignedInteger in project buck by facebook.

the class MachoMagicInfoUtils method getMachMagicInfo.

/**
   * Reads 4 bytes from the given byte buffer from position 0 and produces the MachoMagicInfo object
   * which describes basic information about Mach Object file.
   * @param buffer Byte Buffer which holds bytes for the mach header magic number.
   * @return MachoMagicInfo object.
   * @throws IOException
   */
public static MachoMagicInfo getMachMagicInfo(ByteBuffer buffer) {
    ByteOrder order = buffer.order();
    UnsignedInteger magic = UnsignedInteger.fromIntBits(buffer.order(ByteOrder.BIG_ENDIAN).getInt());
    buffer.order(order);
    return new MachoMagicInfo(magic);
}
Also used : ByteOrder(java.nio.ByteOrder) UnsignedInteger(com.google.common.primitives.UnsignedInteger)

Example 5 with UnsignedInteger

use of com.google.common.primitives.UnsignedInteger in project buck by facebook.

the class LinkEditDataCommandTest method testUpdatingLinkEditDataCommandInByteBuffer.

@Test
public void testUpdatingLinkEditDataCommandInByteBuffer() throws Exception {
    LinkEditDataCommand command = LinkEditDataCommandUtils.createFromBuffer(ByteBuffer.wrap(LinkEditCommandTestData.getCodeSignBigEndian()).order(ByteOrder.BIG_ENDIAN));
    UnsignedInteger newValue = UnsignedInteger.fromIntBits(0xFE);
    LinkEditDataCommand updated = command.withDataoff(newValue);
    ByteBuffer buffer = ByteBuffer.allocate(command.getLoadCommandCommonFields().getCmdsize().intValue()).order(ByteOrder.BIG_ENDIAN);
    LinkEditDataCommandUtils.updateLinkEditDataCommand(buffer, command, updated);
    buffer.position(0);
    LinkEditDataCommand commandCreatedFromBuffer = LinkEditDataCommandUtils.createFromBuffer(buffer);
    ByteBuffer newBuffer = ByteBuffer.allocate(commandCreatedFromBuffer.getLoadCommandCommonFields().getCmdsize().intValue()).order(ByteOrder.BIG_ENDIAN);
    LinkEditDataCommandUtils.writeCommandToBuffer(commandCreatedFromBuffer, newBuffer);
    assertThat(commandCreatedFromBuffer.getDataoff(), equalToObject(newValue));
    assertThat(buffer.array(), equalTo(newBuffer.array()));
}
Also used : UnsignedInteger(com.google.common.primitives.UnsignedInteger) ByteBuffer(java.nio.ByteBuffer) Test(org.junit.Test)

Aggregations

UnsignedInteger (com.google.common.primitives.UnsignedInteger)8 ByteBuffer (java.nio.ByteBuffer)2 Test (org.junit.Test)2 ByteOrder (java.nio.ByteOrder)1 Path (java.nio.file.Path)1 HashMap (java.util.HashMap)1