package com.oracle.objectfile.pecoff;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import com.oracle.objectfile.pecoff.PECoff.IMAGE_SECTION_HEADER;
final class PECoffSectionStruct {
private final ByteBuffer section;
private final int sectionIndex;
private final int align;
PECoffSectionStruct(String sectName, int sectFlags0, int sectAlign, int sectIndex) {
section = PECoffByteBuffer.allocate(IMAGE_SECTION_HEADER.totalsize);
byte[] sectionName = sectName.getBytes(StandardCharsets.UTF_8);
int max = sectionName.length <= IMAGE_SECTION_HEADER.Name.sz ? sectionName.length : IMAGE_SECTION_HEADER.Name.sz;
assert !(sectAlign < 1 || sectAlign > 1024 || (sectAlign & (sectAlign - 1)) != 0) : "section alignment is not valid: " + sectAlign;
align = sectAlign;
int sectAlignBits = (32 - Integer.numberOfLeadingZeros(align)) << IMAGE_SECTION_HEADER.IMAGE_SCN_ALIGN_SHIFT;
int sectFlags = (sectFlags0 & ~IMAGE_SECTION_HEADER.IMAGE_SCN_ALIGN_MASK) | (sectAlignBits & IMAGE_SECTION_HEADER.IMAGE_SCN_ALIGN_MASK);
section.put(sectionName, IMAGE_SECTION_HEADER.Name.off, max);
section.putInt(IMAGE_SECTION_HEADER.VirtualSize.off, 0);
section.putInt(IMAGE_SECTION_HEADER.VirtualAddress.off, 0);
section.putInt(IMAGE_SECTION_HEADER.PointerToLinenumbers.off, 0);
section.putChar(IMAGE_SECTION_HEADER.NumberOfLinenumbers.off, (char) 0);
section.putInt(IMAGE_SECTION_HEADER.Characteristics.off, sectFlags);
sectionIndex = sectIndex;
}
int getSize() {
return section.getInt(IMAGE_SECTION_HEADER.SizeOfRawData.off);
}
int getDataAlign() {
return (align);
}
static int getShdrAlign() {
return (4);
}
byte[] getArray() {
return section.array();
}
void setOffset(int offset) {
section.putInt(IMAGE_SECTION_HEADER.PointerToRawData.off, offset);
}
void setSize(int size) {
section.putInt(IMAGE_SECTION_HEADER.SizeOfRawData.off, size);
}
void setVirtualAddress(int addr) {
section.putInt(IMAGE_SECTION_HEADER.VirtualAddress.off, addr);
}
int getOffset() {
return (section.getInt(IMAGE_SECTION_HEADER.PointerToRawData.off));
}
void setReloff(int offset) {
section.putInt(IMAGE_SECTION_HEADER.PointerToRelocations.off, offset);
}
void setRelcount(int count) {
if (count > 0xFFFF) {
int flags;
section.putChar(IMAGE_SECTION_HEADER.NumberOfRelocations.off, (char) 0xFFFF);
flags = section.getInt(IMAGE_SECTION_HEADER.Characteristics.off);
flags |= IMAGE_SECTION_HEADER.IMAGE_SCN_LNK_NRELOC_OVFL;
section.putInt(IMAGE_SECTION_HEADER.Characteristics.off, flags);
} else {
section.putChar(IMAGE_SECTION_HEADER.NumberOfRelocations.off, (char) count);
}
}
int getSectionId() {
return sectionIndex;
}
}