Search in sources :

Example 31 with MappedByteBuffer

use of java.nio.MappedByteBuffer in project buck by facebook.

the class Machos method relativizeOsoSymbols.

static void relativizeOsoSymbols(FileChannel file, ImmutableCollection<Path> cellRoots) throws IOException, MachoException {
    for (Path root : cellRoots) {
        Preconditions.checkState(root.isAbsolute());
    }
    long size = file.size();
    MappedByteBuffer map = file.map(FileChannel.MapMode.READ_WRITE, 0, size);
    MachoHeader header = getHeader(map);
    int symbolTableOffset = 0;
    int symbolTableCount = 0;
    int stringTableOffset = 0;
    int stringTableSizePosition = 0;
    int stringTableSize = 0;
    boolean symbolTableSegmentFound = false;
    int segmentSizePosition = 0;
    int segmentSize = 0;
    int commandsCount = header.getCommandsCount();
    for (int i = 0; i < commandsCount; i++) {
        // NOPMD
        int commandStart = map.position();
        int command = ObjectFileScrubbers.getLittleEndianInt(map);
        // NOPMD
        int commandSize = ObjectFileScrubbers.getLittleEndianInt(map);
        switch(command) {
            case LC_SYMTAB:
                symbolTableOffset = ObjectFileScrubbers.getLittleEndianInt(map);
                symbolTableCount = ObjectFileScrubbers.getLittleEndianInt(map);
                stringTableOffset = ObjectFileScrubbers.getLittleEndianInt(map);
                stringTableSizePosition = map.position();
                stringTableSize = ObjectFileScrubbers.getLittleEndianInt(map);
                symbolTableSegmentFound = true;
                break;
            case LC_SEGMENT:
                /* segment name */
                ObjectFileScrubbers.getBytes(map, 16);
                /* vm address */
                ObjectFileScrubbers.getLittleEndianInt(map);
                /* vm size */
                ObjectFileScrubbers.getLittleEndianInt(map);
                int segmentFileOffset = ObjectFileScrubbers.getLittleEndianInt(map);
                int segmentFileSizePosition = map.position();
                int segmentFileSize = ObjectFileScrubbers.getLittleEndianInt(map);
                /* maximum vm protection */
                ObjectFileScrubbers.getLittleEndianInt(map);
                /* initial vm protection */
                ObjectFileScrubbers.getLittleEndianInt(map);
                /* number of sections */
                ObjectFileScrubbers.getLittleEndianInt(map);
                /* flags */
                ObjectFileScrubbers.getLittleEndianInt(map);
                if (segmentFileOffset + segmentFileSize == size) {
                    if (segmentSizePosition != 0) {
                        throw new MachoException("multiple map segment commands map string table");
                    }
                    segmentSizePosition = segmentFileSizePosition;
                    segmentSize = segmentFileSize;
                }
                break;
            case LC_SEGMENT_64:
                /* segment name */
                ObjectFileScrubbers.getBytes(map, 16);
                /* vm address */
                ObjectFileScrubbers.getLittleEndianLong(map);
                /* vm size */
                ObjectFileScrubbers.getLittleEndianLong(map);
                long segment64FileOffset = ObjectFileScrubbers.getLittleEndianLong(map);
                int segment64FileSizePosition = map.position();
                long segment64FileSize = ObjectFileScrubbers.getLittleEndianLong(map);
                /* maximum vm protection */
                ObjectFileScrubbers.getLittleEndianInt(map);
                /* initial vm protection */
                ObjectFileScrubbers.getLittleEndianInt(map);
                /* number of sections */
                ObjectFileScrubbers.getLittleEndianInt(map);
                /* flags */
                ObjectFileScrubbers.getLittleEndianInt(map);
                if (segment64FileOffset + segment64FileSize == size) {
                    if (segmentSizePosition != 0) {
                        throw new MachoException("multiple map segment commands map string table");
                    }
                    segmentSizePosition = segment64FileSizePosition;
                    if (segment64FileSize > Ints.MAX_POWER_OF_TWO) {
                        throw new MachoException("map segment file size too big");
                    }
                    segmentSize = (int) segment64FileSize;
                }
                break;
        }
        map.position(commandStart + commandSize);
    }
    if (!symbolTableSegmentFound) {
        throw new MachoException("LC_SYMTAB command not found");
    }
    if (stringTableOffset + stringTableSize != size) {
        throw new MachoException("String table does not end at end of file");
    }
    if (stringTableSize == 0) {
        return;
    }
    if (segmentSizePosition == 0 || segmentSize == 0) {
        throw new MachoException("LC_SEGMENT or LC_SEGMENT_64 command for string table not found");
    }
    map.position(stringTableOffset);
    if (map.get() != 0x20) {
        throw new MachoException("First character in the string table is not a space");
    }
    if (map.get() != 0x00) {
        throw new MachoException("Second character in the string table is not a NUL");
    }
    int currentStringTableOffset = map.position();
    byte[] stringTableBytes = new byte[stringTableSize];
    map.position(stringTableOffset);
    map.get(stringTableBytes);
    ByteBuffer stringTable = ByteBuffer.wrap(stringTableBytes);
    map.position(symbolTableOffset);
    Map<Integer, Integer> strings = new HashMap<>();
    for (int i = 0; i < symbolTableCount; i++) {
        int stringTableIndexPosition = map.position();
        int stringTableIndex = ObjectFileScrubbers.getLittleEndianInt(map);
        byte type = map.get();
        /* section */
        map.get();
        /* description */
        ObjectFileScrubbers.getLittleEndianShort(map);
        int valuePosition = map.position();
        if (header.getIs64Bit()) {
            /* value */
            ObjectFileScrubbers.getLittleEndianLong(map);
        } else {
            /* value */
            ObjectFileScrubbers.getLittleEndianInt(map);
        }
        if (stringTableIndex < 2) {
            continue;
        }
        int position = map.position();
        try {
            int newStringTableIndex;
            if (strings.containsKey(stringTableIndex)) {
                newStringTableIndex = strings.get(stringTableIndex);
            } else {
                stringTable.position(stringTableIndex);
                String string = ObjectFileScrubbers.getAsciiString(stringTable);
                if (type == N_OSO) {
                    for (Path root : cellRoots) {
                        String rootPrefix = root + "/";
                        Optional<String> fixed = MoreStrings.stripPrefix(string, rootPrefix).map(input -> "./" + input);
                        if (fixed.isPresent()) {
                            string = fixed.get();
                            break;
                        }
                    }
                    map.position(valuePosition);
                    int lastModifiedValue = ObjectFileCommonModificationDate.COMMON_MODIFICATION_TIME_STAMP;
                    if (header.getIs64Bit()) {
                        ObjectFileScrubbers.putLittleEndianLong(map, lastModifiedValue);
                    } else {
                        ObjectFileScrubbers.putLittleEndianInt(map, lastModifiedValue);
                    }
                }
                map.position(currentStringTableOffset);
                ObjectFileScrubbers.putAsciiString(map, string);
                newStringTableIndex = currentStringTableOffset - stringTableOffset;
                currentStringTableOffset = map.position();
                strings.put(stringTableIndex, newStringTableIndex);
            }
            map.position(stringTableIndexPosition);
            ObjectFileScrubbers.putLittleEndianInt(map, newStringTableIndex);
        } finally {
            map.position(position);
        }
    }
    map.position(stringTableSizePosition);
    int newStringTableSize = currentStringTableOffset - stringTableOffset;
    ObjectFileScrubbers.putLittleEndianInt(map, newStringTableSize);
    map.position(segmentSizePosition);
    ObjectFileScrubbers.putLittleEndianInt(map, segmentSize + (newStringTableSize - stringTableSize));
    file.truncate(currentStringTableOffset);
}
Also used : Path(java.nio.file.Path) HashMap(java.util.HashMap) ByteBuffer(java.nio.ByteBuffer) MappedByteBuffer(java.nio.MappedByteBuffer) MappedByteBuffer(java.nio.MappedByteBuffer)

Example 32 with MappedByteBuffer

use of java.nio.MappedByteBuffer in project buck by facebook.

the class Machos method isMacho.

static boolean isMacho(FileChannel file) throws IOException {
    MappedByteBuffer map = file.map(FileChannel.MapMode.READ_ONLY, 0, MH_MAGIC.length);
    byte[] magic = ObjectFileScrubbers.getBytes(map, MH_MAGIC.length);
    return Arrays.equals(MH_MAGIC, magic) || Arrays.equals(MH_CIGAM, magic) || Arrays.equals(MH_MAGIC_64, magic) || Arrays.equals(MH_CIGAM_64, magic);
}
Also used : MappedByteBuffer(java.nio.MappedByteBuffer)

Example 33 with MappedByteBuffer

use of java.nio.MappedByteBuffer in project buck by facebook.

the class MungingDebugPathSanitizer method restore.

protected void restore(Path path, ByteBufferReplacer replacer) throws IOException {
    try (FileChannel channel = FileChannel.open(path, READ, WRITE)) {
        MappedByteBuffer buffer = channel.map(READ_WRITE, 0, channel.size());
        restore(buffer, replacer);
    }
}
Also used : MappedByteBuffer(java.nio.MappedByteBuffer) FileChannel(java.nio.channels.FileChannel)

Example 34 with MappedByteBuffer

use of java.nio.MappedByteBuffer in project OpenGrok by OpenGrok.

the class ELFAnalyzer method parseELF.

public String parseELF(FileChannel fch) throws IOException {
    MappedByteBuffer fmap = fch.map(FileChannel.MapMode.READ_ONLY, 0, fch.size());
    ELFHeader eh = new ELFHeader(fmap);
    if (eh.e_shnum <= 0) {
        LOGGER.log(Level.FINE, "Skipping file, no section headers");
        return null;
    }
    fmap.position(eh.e_shoff + (eh.e_shstrndx * eh.e_shentsize));
    ELFSection stringSection = new ELFSection(fmap);
    if (stringSection.sh_size == 0) {
        LOGGER.log(Level.FINE, "Skipping file, no section name string table");
        return null;
    }
    HashMap<String, Integer> sectionMap = new HashMap<String, Integer>();
    ELFSection[] sections = new ELFSection[eh.e_shnum];
    int[] readables = new int[eh.e_shnum];
    int ri = 0;
    for (int i = 0; i < eh.e_shnum; i++) {
        fmap.position(eh.e_shoff + (i * eh.e_shentsize));
        sections[i] = new ELFSection(fmap);
        String sectionName = getName(stringSection.sh_offset, sections[i].sh_name, fmap);
        if (sectionName != null) {
            sectionMap.put(sectionName, sections[i].sh_offset);
        }
        if (sections[i].sh_type == ELFSection.SHT_STRTAB) {
            readables[ri++] = i;
        } else if (READABLE_SECTIONS.contains(sectionName)) {
            readables[ri++] = i;
        }
    }
    boolean lastPrintable = false;
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < ri; i++) {
        fmap.position(sections[readables[i]].sh_offset);
        int size = sections[readables[i]].sh_size;
        byte c;
        while (size-- > 0) {
            c = fmap.get();
            if (isReadable(c)) {
                lastPrintable = true;
                sb.append((char) c);
            } else if (lastPrintable) {
                lastPrintable = false;
                sb.append(' ');
            }
        }
        sb.append('\n');
    }
    return sb.toString();
}
Also used : HashMap(java.util.HashMap) MappedByteBuffer(java.nio.MappedByteBuffer)

Example 35 with MappedByteBuffer

use of java.nio.MappedByteBuffer in project mapdb by jankotek.

the class ByteBufferVol method unmap.

/**
     * Hack to unmap MappedByteBuffer.
     * Unmap is necessary on Windows, otherwise file is locked until JVM exits or BB is GCed.
     * There is no public JVM API to unmap buffer, so this tries to use SUN proprietary API for unmap.
     * Any error is silently ignored (for example SUN API does not exist on Android).
     */
protected static boolean unmap(MappedByteBuffer b) {
    if (!unmapHackSupported) {
        return false;
    }
    if (!(b instanceof DirectBuffer))
        return false;
    // need to dispose old direct buffer, see bug
    // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4724038
    DirectBuffer bb = (DirectBuffer) b;
    Cleaner c = bb.cleaner();
    if (c != null) {
        c.clean();
        return true;
    }
    Object attachment = bb.attachment();
    return attachment != null && attachment instanceof DirectBuffer && attachment != b && unmap((MappedByteBuffer) attachment);
}
Also used : DirectBuffer(sun.nio.ch.DirectBuffer) MappedByteBuffer(java.nio.MappedByteBuffer) Cleaner(sun.misc.Cleaner)

Aggregations

MappedByteBuffer (java.nio.MappedByteBuffer)154 FileChannel (java.nio.channels.FileChannel)75 IOException (java.io.IOException)44 File (java.io.File)38 RandomAccessFile (java.io.RandomAccessFile)36 FileInputStream (java.io.FileInputStream)29 ByteBuffer (java.nio.ByteBuffer)24 Test (org.junit.Test)18 Path (java.nio.file.Path)11 ProjectWorkspace (com.facebook.buck.testutil.integration.ProjectWorkspace)9 Elf (com.facebook.buck.cxx.elf.Elf)8 FileOutputStream (java.io.FileOutputStream)8 ElfSection (com.facebook.buck.cxx.elf.ElfSection)6 FileNotFoundException (java.io.FileNotFoundException)5 ProjectFilesystem (com.facebook.buck.io.ProjectFilesystem)4 UnsafeBuffer (org.agrona.concurrent.UnsafeBuffer)4 Pair (com.facebook.buck.model.Pair)3 Date (java.util.Date)3 NulTerminatedCharsetDecoder (com.facebook.buck.charset.NulTerminatedCharsetDecoder)2 ElfDynamicSection (com.facebook.buck.cxx.elf.ElfDynamicSection)2