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);
}
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);
}
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);
}
}
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();
}
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);
}
Aggregations