Browse Source

[PATCH 009/188] updating renaming export entries

From a15a2d961684c96837cc57b09193fdb499ae4fa8 Mon Sep 17 00:00:00 2001
From: Dmitry Boyarintsev <[email protected]>
Date: Thu, 26 Sep 2019 01:34:58 -0400

git-svn-id: branches/wasm@46005 -
nickysn 5 years ago
parent
commit
18910afe47
4 changed files with 250 additions and 25 deletions
  1. 59 12
      utils/wasmbin/wasmbin.pas
  2. 2 2
      utils/wasmbin/wasmld.lpi
  3. 123 5
      utils/wasmbin/wasmld.lpr
  4. 66 6
      utils/wasmbin/wasmlinkchange.pas

+ 59 - 12
utils/wasmbin/wasmbin.pas

@@ -28,18 +28,18 @@ const
   WasmId_Int = $6D736100;
   WasmId_Int = $6D736100;
 
 
 const
 const
-  sect_custom   = 0;	// custom section
-  sect_type     = 1;	// type section
-  sect_import   = 2;	// import section
-  sect_function = 3;	// function section
-  sect_table    = 4;	// table section
-  sect_memory   = 5;	// memory section
-  sect_global   = 6;	// global section
-  sect_export   = 7;	// export section
-  sect_start    = 8;	// start section
-  sect_element  = 9;	// element section
-  sect_code     = 10;	// code section
-  sect_data     = 11;	// data section
+  SECT_CUSTOM   = 0;	// custom section
+  SECT_TYPE     = 1;	// type section
+  SECT_IMPORT   = 2;	// import section
+  SECT_FUNCTION = 3;	// function section
+  SECT_TABLE    = 4;	// table section
+  SECT_MEMORY   = 5;	// memory section
+  SECT_GLOBAL   = 6;	// global section
+  SECT_EXPORT   = 7;	// export section
+  SECT_START    = 8;	// start section
+  SECT_ELEMENT  = 9;	// element section
+  SECT_CODE     = 10;	// code section
+  SECT_DATA     = 11;	// data section
 
 
 type
 type
   TSection = packed record
   TSection = packed record
@@ -87,6 +87,17 @@ type
     entries : array of TCodeEntry;
     entries : array of TCodeEntry;
   end;
   end;
 
 
+
+  TExportEntry = record
+    name    : string;
+    desc    : byte;
+    index   : UInt32;
+  end;
+
+  TExportSection = record
+    entries : array of TExportEntry;
+  end;
+
 function SectionIdToStr(id: integer): string;
 function SectionIdToStr(id: integer): string;
 function ValTypeToStr(id: integer): string;
 function ValTypeToStr(id: integer): string;
 
 
@@ -106,6 +117,12 @@ procedure ReadCodeEntry(src: TStream; var en: TCodeEntry);
 // reads the code entry into TCodeEntry structure
 // reads the code entry into TCodeEntry structure
 procedure ReadCodeSection(src: TStream; var sc: TCodeSection);
 procedure ReadCodeSection(src: TStream; var sc: TCodeSection);
 
 
+
+procedure ReadExportEntry(src: TStream; var ex: TExportEntry);
+// reads the export entry
+procedure ReadExport(src: TStream; var ex: TExportSection);
+procedure WriteExport(const ex: TExportSection; dst: TStream);
+
 implementation
 implementation
 
 
 function ValTypeToStr(id: integer): string;
 function ValTypeToStr(id: integer): string;
@@ -199,5 +216,35 @@ begin
     ReadCodeEntry(src, sc.entries[i]);
     ReadCodeEntry(src, sc.entries[i]);
 end;
 end;
 
 
+procedure ReadExportEntry(src: TStream; var ex: TExportEntry);
+begin
+  ex.name := ReadName(src);
+  ex.desc := src.ReadByte;
+  ex.index := ReadU(src);
+end;
+
+procedure ReadExport(src: TStream; var ex: TExportSection);
+var
+  cnt : integer;
+  i   : integer;
+begin
+  cnt := ReadU(src);
+  SetLength(ex.entries, cnt);
+  for i:=0 to cnt-1 do
+    ReadExportEntry(src, ex.entries[i]);
+end;
+
+procedure WriteExport(const ex: TExportSection; dst: TStream);
+var
+  i : integer;
+begin
+  WriteU32(dst, length(ex.entries));
+  for i:=0 to length(ex.entries)-1 do begin
+    WriteName(dst, ex.entries[i].name);
+    dst.WriteByte(ex.entries[i].desc);
+    WriteU32(dst, ex.entries[i].index);
+  end;
+end;
+
 end.
 end.
 
 

+ 2 - 2
utils/wasmbin/wasmld.lpi

@@ -1,16 +1,16 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <?xml version="1.0" encoding="UTF-8"?>
 <CONFIG>
 <CONFIG>
   <ProjectOptions>
   <ProjectOptions>
-    <Version Value="11"/>
+    <Version Value="12"/>
     <PathDelim Value="\"/>
     <PathDelim Value="\"/>
     <General>
     <General>
       <Flags>
       <Flags>
         <MainUnitHasCreateFormStatements Value="False"/>
         <MainUnitHasCreateFormStatements Value="False"/>
         <MainUnitHasTitleStatement Value="False"/>
         <MainUnitHasTitleStatement Value="False"/>
         <MainUnitHasScaledStatement Value="False"/>
         <MainUnitHasScaledStatement Value="False"/>
+        <CompatibilityMode Value="True"/>
       </Flags>
       </Flags>
       <SessionStorage Value="InProjectDir"/>
       <SessionStorage Value="InProjectDir"/>
-      <MainUnit Value="0"/>
       <Title Value="wasmld"/>
       <Title Value="wasmld"/>
       <UseAppBundle Value="False"/>
       <UseAppBundle Value="False"/>
       <ResourceType Value="res"/>
       <ResourceType Value="res"/>

+ 123 - 5
utils/wasmbin/wasmld.lpr

@@ -62,7 +62,7 @@ begin
 end;
 end;
 
 
 
 
-function WriteStream(st: TStream): Boolean;
+function WriteStream(st: TStream; syms: TStrings): Boolean;
 var
 var
   dw  : LongWord;
   dw  : LongWord;
   ofs : int64;
   ofs : int64;
@@ -92,7 +92,7 @@ begin
       writeln(nm);
       writeln(nm);
       if nm = SectionName_Linking then begin
       if nm = SectionName_Linking then begin
         writeln('rewriting linking...');
         writeln('rewriting linking...');
-        ProcessLinkingSection(st);
+        ProcessLinkingSection(st, syms);
         break;
         break;
       end;
       end;
         //DumpLinking(st, sc.size - (st.Position - ofs));
         //DumpLinking(st, sc.size - (st.Position - ofs));
@@ -107,27 +107,145 @@ begin
   end;
   end;
 end;
 end;
 
 
-procedure ProcessWasmFile(const fn: string);
+procedure ProcessWasmFile(const fn, symfn: string);
 var
 var
   fs :TFileStream;
   fs :TFileStream;
+  syms:  TStringList;
 begin
 begin
   writeln('proc: ', fn);
   writeln('proc: ', fn);
+  syms:=TStringList.Create;
   fs := TFileStream.Create(fn, fmOpenReadWrite or fmShareDenyNone);
   fs := TFileStream.Create(fn, fmOpenReadWrite or fmShareDenyNone);
   try
   try
+    if (symfn<>'') then
+      ReadSymbolsConf(symfn, syms);
     writeln('size: ', fs.size);
     writeln('size: ', fs.size);
-    WriteStream(fs);
+    WriteStream(fs, syms);
   finally
   finally
     fs.Free;
     fs.Free;
+    syms.Free;
   end;
   end;
 end;
 end;
 
 
+procedure RenameExport(var x: TExportSection; syms: TStrings);
+var
+  i : integer;
+  v : string;
+begin
+  for i:=0 to length(x.entries)-1 do begin
+    v := syms.Values[x.entries[i].name];
+    if v <> '' then
+      x.entries[i].name := v;
+  end;
+end;
+
+function ProcessSections(st, dst: TStream; syms: TStrings): Boolean;
+var
+  dw  : LongWord;
+  ofs : int64;
+  sc  : TSection;
+  ps  : int64;
+  x   : TExportSection;
+  i   : integer;
+  mem : TMemoryStream;
+begin
+  dw := st.ReadDWord;
+  Result := dw = WasmId_Int;
+  if not Result then begin
+    Exit;
+  end;
+  dw := st.ReadDWord;
+  while st.Position<st.Size do begin
+    ofs := st.Position;
+    sc.id := st.ReadByte;
+    sc.Size := ReadU(st);
+    writeln(ofs,': id=', sc.id,'(', SectionIdToStr(sc.id),') sz=', sc.size);
+
+    ps := st.Position+sc.size;
+
+    if sc.id = SECT_EXPORT then begin
+      ReadExport(st, x);
+      RenameExport(x, syms);
+
+      st.Position:=0;
+      dst.CopyFrom(st, ofs);
+      st.Position:=ps;
+
+      mem := TMemoryStream.Create;
+      WriteExport(x, mem);
+      mem.Position:=0;
+
+      dst.WriteByte(SECT_EXPORT);
+      WriteU32(dst, mem.Size);
+      dst.CopyFrom(mem, mem.Size);
+
+      writeln('entries = ', length(x.entries));
+      for i:=0 to length(x.entries)-1 do begin
+        writeln(x.entries[i].desc,' ', x.entries[i].name)
+      end;
+
+      dst.CopyFrom(st, st.Size-st.Position);
+      break; // done
+    end;
+    {if sc.id=0 then begin
+      nm := GetName(st);
+      writeln(nm);
+      if nm = SectionName_Linking then begin
+        writeln('rewriting linking...');
+        ProcessLinkingSection(st, syms);
+        break;
+      end;
+        //DumpLinking(st, sc.size - (st.Position - ofs));
+    end;}
+    //if sc.id= 1 then DumpTypes(st);
+
+    if st.Position <> ps then
+    begin
+      //writeln('adjust stream targ=',ps,' actual: ', st.position);
+      st.Position := ps;
+    end;
+  end;
+end;
+
+
+procedure ProcessWasmSection(const fn, {%H-}symfn: string);
+var
+  fs    : TFileStream;
+  syms  : TStringList;
+  dst   : TMemoryStream;
+begin
+  writeln('proc: ', fn);
+  syms:=TStringList.Create;
+  fs := TFileStream.Create(fn, fmOpenReadWrite or fmShareDenyNone);
+  dst := TMemoryStream.Create;
+  try
+    if (symfn <> '') and fileExists(symfn) then
+      syms.LoadFromFile(symfn);
+
+    ProcessSections(fs, dst, syms);
+    fs.Position:=0;
+    dst.Position:=0;
+    fs.CopyFrom(dst, dst.Size);
+    fs.Size:=dst.Size;
+
+  finally
+    dst.Free;
+    fs.Free;
+    syms.Free;
+  end;
+end;
+
+var
+  symfn : string;
 begin
 begin
   if ParamCount=0 then begin
   if ParamCount=0 then begin
     writeln('please specify .wasm file');
     writeln('please specify .wasm file');
     exit;
     exit;
   end;
   end;
+  symfn:='';
+  if ParamCount>1 then symfn:=ParamStr(2);
 
 
   //ReadWasmFile(ParamStr(1));
   //ReadWasmFile(ParamStr(1));
-  ProcessWasmFile(ParamStr(1));
+  //ProcessWasmFile(ParamStr(1), symfn);
+  ProcessWasmSection(ParamStr(1), symfn);
 end.
 end.
 
 

+ 66 - 6
utils/wasmbin/wasmlinkchange.pas

@@ -4,11 +4,55 @@ interface
 
 
 uses Classes, SysUtils, wasmlink, wasmbin, lebutils;
 uses Classes, SysUtils, wasmlink, wasmbin, lebutils;
 
 
-procedure ProcessLinkingSection(st: TStream);
+type
+  TSymbolType = (
+    st_Nochange, st_Hidden, st_Weak
+  );
+
+  TSymbolConfigure = class(TObject)
+    symname  : string;
+    needtype : TSymbolType;
+  end;
+
+procedure ReadSymbolsConf(const fn: string; dst: TStrings);
+procedure ReadSymbolsConf(src: TStream; dst: TStrings);
+
+procedure ProcessLinkingSection(st: TStream; syms: TStrings);
 
 
 implementation
 implementation
 
 
-procedure ProcessLinkingSection(st: TStream);
+procedure ReadSymbolsConf(const fn: string; dst: TStrings);
+var
+  fs: TFileStream;
+begin
+  fs:=TFileStream.Create(fn, fmOpenRead or fmShareDenyNone);
+  try
+    ReadSymbolsConf(fs, dst);
+  finally
+    fs.Free;
+  end;
+end;
+
+function StrToSymType(const s: string): TSymbolType;
+begin
+  if length(s)=0 then
+    Result:=st_Nochange
+  else
+  case upCase(s[1]) of
+    'H','L': Result:=st_Hidden;
+    'W': Result:=st_Weak;
+  else
+    Result:=st_Nochange;
+  end;
+end;
+
+
+procedure ReadSymbolsConf(src: TStream; dst: TStrings);
+begin
+  dst.LoadFromStream(src);
+end;
+
+procedure ProcessLinkingSection(st: TStream; syms: TStrings);
 var
 var
   mt  : TLinkingMetadata;
   mt  : TLinkingMetadata;
   //en  : Int64;
   //en  : Int64;
@@ -18,6 +62,9 @@ var
   i   : integer;
   i   : integer;
   si  : TSymInfo;
   si  : TSymInfo;
   ofs : Int64;
   ofs : Int64;
+  v   : string;
+  tt  : TSymbolType;
+  fl  : LongWord;
 begin
 begin
   //en := st.Position+secsize;
   //en := st.Position+secsize;
   ReadMetadata(st, mt);
   ReadMetadata(st, mt);
@@ -37,11 +84,24 @@ begin
       //write(SymKindToStr(si.kind),' ',IntToHex(si.flags,8));
       //write(SymKindToStr(si.kind),' ',IntToHex(si.flags,8));
       //if si.hasSymName then write(' ',si.symname);
       //if si.hasSymName then write(' ',si.symname);
       //writeln;
       //writeln;
-      if si.flags and WASM_SYM_UNDEFINED = 0 then
-        si.flags := si.flags or WASM_SYM_BINDING_LOCAL;
 
 
-      st.Position := ofs;
-      WriteSymInfo(st, si);
+      if si.hasSymName then begin
+        v := syms.Values[si.symname];
+        tt := StrToSymType(v);
+
+        fl := si.flags;
+        case tt of
+          st_Hidden:
+            si.flags := (si.flags or WASM_SYM_BINDING_LOCAL) and (not WASM_SYM_BINDING_WEAK) and (not WASM_SYM_UNDEFINED);
+          st_Weak:
+            si.flags := (si.flags or WASM_SYM_BINDING_WEAK) and (not WASM_SYM_BINDING_LOCAL)
+        end;
+
+        if fl <> si.flags then begin
+          st.Position := ofs;
+          WriteSymInfo(st, si);
+        end;
+      end;
 
 
       //writeln(si.symname);
       //writeln(si.symname);
     end;
     end;