package jdk.tools.jaotc.binformat.pecoff;
import java.nio.ByteBuffer;
import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_SECTION_HEADER;
final class PECoffSection {
private final ByteBuffer section;
private final byte[] data;
private final boolean hasrelocations;
private final int sectionIndex;
private final int align;
PECoffSection(String sectName, byte[] sectData0, int sectFlags0, int sectAlign, boolean hasRelocations, int sectIndex) {
section = PECoffByteBuffer.allocate(IMAGE_SECTION_HEADER.totalsize);
byte[] sectData = sectData0;
if (sectData0.length == 0) {
sectData = new byte[8];
}
byte[] name = sectName.getBytes();
int max = name.length <= IMAGE_SECTION_HEADER.Name.sz ? name.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(name, 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.SizeOfRawData.off, sectData.length);
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);
data = sectData;
hasrelocations = hasRelocations;
sectionIndex = sectIndex;
}
long getSize() {
return section.getInt(IMAGE_SECTION_HEADER.SizeOfRawData.off);
}
int getDataAlign() {
return (align);
}
static int getShdrAlign() {
return (4);
}
byte[] getArray() {
return section.array();
}
byte[] getDataArray() {
return data;
}
void setOffset(long offset) {
section.putInt(IMAGE_SECTION_HEADER.PointerToRawData.off, (int) offset);
}
long 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);
}
}
boolean hasRelocations() {
return hasrelocations;
}
int getSectionId() {
return sectionIndex;
}
}