mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-16 10:19:17 +02:00
[PATCH 004/188] update reading symbol info
From 520a5340b636c24726426126b864f486b243821d Mon Sep 17 00:00:00 2001 From: Dmitry Boyarintsev <skalogryz.lists@gmail.com> Date: Wed, 25 Sep 2019 10:12:27 -0400 git-svn-id: branches/wasm@46000 -
This commit is contained in:
parent
64027a4527
commit
113c995843
@ -8,6 +8,15 @@ uses
|
|||||||
function ReadU(src: TStream): UInt64;
|
function ReadU(src: TStream): UInt64;
|
||||||
function ReadS(src: TStream; bits: Integer): Int64;
|
function ReadS(src: TStream; bits: Integer): Int64;
|
||||||
|
|
||||||
|
procedure WriteU8 (src: TStream; vl: UInt8);
|
||||||
|
procedure WriteU16(src: TStream; vl: UInt16);
|
||||||
|
procedure WriteU32(src: TStream; vl: UInt32);
|
||||||
|
procedure WriteU64(src: TStream; vl: UInt64);
|
||||||
|
procedure WriteS8 (src: TStream; vl: Int8);
|
||||||
|
procedure WriteS16(src: TStream; vl: Int16);
|
||||||
|
procedure WriteS32(src: TStream; vl: Int32);
|
||||||
|
procedure WriteS64(src: TStream; vl: Int64);
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
function ReadU(src: TStream): UInt64;
|
function ReadU(src: TStream): UInt64;
|
||||||
@ -44,4 +53,39 @@ begin
|
|||||||
result := result or ( (not 0) shl sh);
|
result := result or ( (not 0) shl sh);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure WriteU8(src: TStream; vl: UInt8);
|
||||||
|
begin
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure WriteU16(src: TStream; vl: UInt16);
|
||||||
|
begin
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure WriteU32(src: TStream; vl: UInt32);
|
||||||
|
begin
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure WriteU64(src: TStream; vl: UInt64);
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure WriteS8 (src: TStream; vl: Int8);
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure WriteS16(src: TStream; vl: Int16);
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure WriteS32(src: TStream; vl: Int32);
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure WriteS64(src: TStream; vl: Int64);
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
@ -94,6 +94,7 @@ function ValTypeToStr(id: integer): string;
|
|||||||
// the name consists of
|
// the name consists of
|
||||||
// size - in butes Leb128
|
// size - in butes Leb128
|
||||||
// bytes - in utf8 format
|
// bytes - in utf8 format
|
||||||
|
function ReadName(st: TStream): string;
|
||||||
function GetName(sr: TStream): string;
|
function GetName(sr: TStream): string;
|
||||||
|
|
||||||
// reads
|
// reads
|
||||||
@ -141,13 +142,18 @@ begin
|
|||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function GetName(sr: TStream): string;
|
function ReadName(st: TStream): string;
|
||||||
var
|
var
|
||||||
ln : LongWord;
|
ln : LongWord;
|
||||||
begin
|
begin
|
||||||
ln := ReadU(sr);
|
ln := ReadU(st);
|
||||||
SetLength(result, ln);
|
SetLength(result, ln);
|
||||||
if ln>0 then sr.Read(result[1], ln);
|
if ln>0 then st.Read(result[1], ln);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GetName(sr: TStream): string;
|
||||||
|
begin
|
||||||
|
Result := ReadName(sr);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function GetU32(sr: TStream): UInt32;
|
function GetU32(sr: TStream): UInt32;
|
||||||
|
@ -5,7 +5,7 @@ unit wasmlink;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, lebutils;
|
Classes, SysUtils, lebutils, wasmbin;
|
||||||
|
|
||||||
const
|
const
|
||||||
SectionName_Linking = 'linking';
|
SectionName_Linking = 'linking';
|
||||||
@ -67,10 +67,28 @@ const
|
|||||||
|
|
||||||
type
|
type
|
||||||
TSymInfo = record
|
TSymInfo = record
|
||||||
symkind : UInt8;
|
kind : UInt8;
|
||||||
flags : UInt32;
|
flags : UInt32;
|
||||||
|
|
||||||
|
hasSymIndex : Boolean; // always true for Kind non Data
|
||||||
|
// for Data it's true for defined symbols (see flags);
|
||||||
|
symindex : UInt32; // either symbol or data symbol offset
|
||||||
|
hasSymName : Boolean;
|
||||||
|
symname : string;
|
||||||
|
dataofs : integer; // only if Kind is Data and hasSymIndex = true;
|
||||||
|
datasize : integer;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// The symbol type. One of:
|
||||||
|
const
|
||||||
|
SYMTAB_FUNCTION = 0;
|
||||||
|
SYMTAB_DATA = 1;
|
||||||
|
SYMTAB_GLOBAL = 2;
|
||||||
|
SYMTAB_SECTION = 3;
|
||||||
|
SYMTAB_EVENT = 4;
|
||||||
|
SYMTAB_TABLE = 5;
|
||||||
|
|
||||||
// The current set of valid flags for symbols are:
|
// The current set of valid flags for symbols are:
|
||||||
const
|
const
|
||||||
// Indicating that this is a weak symbol. When linking multiple modules
|
// Indicating that this is a weak symbol. When linking multiple modules
|
||||||
@ -96,6 +114,7 @@ const
|
|||||||
// this must match whether the symbol is an import or is defined;
|
// this must match whether the symbol is an import or is defined;
|
||||||
// for data symbols, determines whether a segment is specified.
|
// for data symbols, determines whether a segment is specified.
|
||||||
WASM_SYM_UNDEFINED = $10;
|
WASM_SYM_UNDEFINED = $10;
|
||||||
|
WASM_SYM_IMPORTED = WASM_SYM_UNDEFINED;
|
||||||
|
|
||||||
// The symbol is intended to be exported from the wasm module to the host
|
// The symbol is intended to be exported from the wasm module to the host
|
||||||
// environment. This differs from the visibility flags in that it effects
|
// environment. This differs from the visibility flags in that it effects
|
||||||
@ -113,17 +132,21 @@ const
|
|||||||
|
|
||||||
function ReadMetaData(st: TStream; out m:TLinkingMetadata): Boolean;
|
function ReadMetaData(st: TStream; out m:TLinkingMetadata): Boolean;
|
||||||
function ReadLinkSubSect(st: TStream; out m: TLinkinSubSection): Boolean;
|
function ReadLinkSubSect(st: TStream; out m: TLinkinSubSection): Boolean;
|
||||||
|
function ReadSymInfo(st: TStream; out m: TSymInfo): Boolean;
|
||||||
|
|
||||||
// dumps linking information. Note: that the name of the "Linking" section
|
// dumps linking information. Note: that the name of the "Linking" section
|
||||||
// must have already been read
|
// must have already been read
|
||||||
procedure DumpLinking(st: TStream; secsize: integer);
|
procedure DumpLinking(st: TStream; secsize: integer);
|
||||||
|
|
||||||
|
function SubSecTypeToStr(b: Byte): string;
|
||||||
|
function SymKindToStr(b: Byte): string;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
function ReadMetaData(st: TStream; out m:TLinkingMetadata): Boolean;
|
function ReadMetaData(st: TStream; out m:TLinkingMetadata): Boolean;
|
||||||
begin
|
begin
|
||||||
FillChar(m, sizeof(m), 0);
|
FillChar(m, sizeof(m), 0);
|
||||||
m.version := ReadU(st);
|
m.version := st.ReadByte;
|
||||||
Result:=true;
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -132,7 +155,36 @@ begin
|
|||||||
FillChar(m, sizeof(m), 0);
|
FillChar(m, sizeof(m), 0);
|
||||||
m.sectype := ReadU(st);
|
m.sectype := ReadU(st);
|
||||||
m.length := ReadU(st);
|
m.length := ReadU(st);
|
||||||
Result:=true;
|
Result := true;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ReadSymInfo(st: TStream; out m: TSymInfo): Boolean;
|
||||||
|
begin
|
||||||
|
FillChar(m, sizeof(m), 0);
|
||||||
|
m.kind := st.ReadByte;
|
||||||
|
m.flags := ReadU(st);
|
||||||
|
|
||||||
|
if m.kind = SYMTAB_DATA then begin
|
||||||
|
m.hasSymName := true; // always exist
|
||||||
|
m.symname := ReadName(st);
|
||||||
|
|
||||||
|
m.hasSymIndex := (m.flags and WASM_SYM_UNDEFINED)=0;
|
||||||
|
if m.hasSymIndex then begin
|
||||||
|
m.symindex := ReadU(st);
|
||||||
|
m.dataofs := ReadU(st);
|
||||||
|
m.datasize := ReadU(st);
|
||||||
|
end;
|
||||||
|
|
||||||
|
end else begin
|
||||||
|
m.hasSymIndex := true; // always exists
|
||||||
|
m.symindex := ReadU(st);
|
||||||
|
|
||||||
|
m.hasSymName := ((m.flags and WASM_SYM_IMPORTED) = 0) or ((m.flags and WASM_SYM_EXPLICIT_NAME) > 0); // imported
|
||||||
|
if m.hasSymName then
|
||||||
|
m.symname:=ReadName(st);
|
||||||
|
end;
|
||||||
|
|
||||||
|
Result := true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure DumpLinking(st: TStream; secsize: integer);
|
procedure DumpLinking(st: TStream; secsize: integer);
|
||||||
@ -140,14 +192,57 @@ var
|
|||||||
mt : TLinkingMetadata;
|
mt : TLinkingMetadata;
|
||||||
en : Int64;
|
en : Int64;
|
||||||
sub : TLinkinSubSection;
|
sub : TLinkinSubSection;
|
||||||
|
cnt : LongWord;
|
||||||
|
nx : Int64;
|
||||||
|
i : integer;
|
||||||
|
si : TSymInfo;
|
||||||
begin
|
begin
|
||||||
en := st.Position+secsize;
|
en := st.Position+secsize;
|
||||||
ReadMetadata(st, mt);
|
ReadMetadata(st, mt);
|
||||||
writeln('version: ', mt.version);
|
writeln('version: ', mt.version);
|
||||||
while st.Position<en do begin
|
while st.Position<en do begin
|
||||||
ReadLinkSubSect(st, sub);
|
ReadLinkSubSect(st, sub);
|
||||||
writeln(sub.sectype);
|
nx := st.Position+sub.length;
|
||||||
st.Position:=st.Position+sub.length;
|
|
||||||
|
writeln('subsec=',SubSecTypeToStr(sub.sectype),' ',sub.sectype);
|
||||||
|
cnt := ReadU(st);
|
||||||
|
writeln('- symbol table [count=', cnt,']');
|
||||||
|
for i:=0 to cnt-1 do begin
|
||||||
|
write(' - ',i,' ');
|
||||||
|
ReadSymInfo(st, si);
|
||||||
|
write(SymKindToStr(si.kind),' ',IntToHex(si.flags,8));
|
||||||
|
if si.hasSymName then write(' ',si.symname);
|
||||||
|
writeln;
|
||||||
|
//writeln(si.symname);
|
||||||
|
end;
|
||||||
|
|
||||||
|
st.Position:=nx;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function SubSecTypeToStr(b: Byte): string;
|
||||||
|
begin
|
||||||
|
case b of
|
||||||
|
WASM_SEGMENT_INFO: Result := 'WASM_SEGMENT_INFO';
|
||||||
|
WASM_INIT_FUNCS: Result := 'WASM_INIT_FUNCS';
|
||||||
|
WASM_COMDAT_INFO: Result := 'WASM_COMDAT_INFO';
|
||||||
|
WASM_SYMBOL_TABLE: Result := 'WASM_SYMBOL_TABLE';
|
||||||
|
else
|
||||||
|
Result := Format('UNKNOWN %d',[b]);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function SymKindToStr(b: Byte): string;
|
||||||
|
begin
|
||||||
|
case b of
|
||||||
|
SYMTAB_FUNCTION: Result := 'F';
|
||||||
|
SYMTAB_DATA: Result := 'D';
|
||||||
|
SYMTAB_GLOBAL: Result := 'G';
|
||||||
|
SYMTAB_SECTION: Result := 'S';
|
||||||
|
SYMTAB_EVENT: Result := 'E';
|
||||||
|
SYMTAB_TABLE: Result := 'T';
|
||||||
|
else
|
||||||
|
Result := 'U'+IntToStR(b);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user