main.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #include <library/cpp/resource/registry.h>
  2. #include <util/stream/file.h>
  3. #include <util/folder/path.h>
  4. using namespace NResource;
  5. class TAsmWriter {
  6. private:
  7. IOutputStream& AsmOut;
  8. TString AsmPrefix;
  9. public:
  10. TAsmWriter(IOutputStream& out, const TString& prefix) : AsmOut(out), AsmPrefix(prefix)
  11. {
  12. }
  13. void Write(TStringBuf filename, const TString& data, bool raw) {
  14. TString constname(Basename(filename));
  15. if (constname.rfind('.') != TStringBuf::npos) {
  16. constname = constname.substr(0, constname.rfind('.'));
  17. }
  18. WriteHeader(constname);
  19. if (raw) {
  20. WriteRaw(constname, data);
  21. } else {
  22. WriteIncBin(constname, filename, data);
  23. }
  24. WriteFooter(constname);
  25. WriteSymbolSize(constname);
  26. }
  27. private:
  28. void WriteHeader(const TStringBuf& constname) {
  29. AsmOut << "global " << AsmPrefix << constname << "\n";
  30. AsmOut << "global " << AsmPrefix << constname << "Size\n";
  31. AsmOut << "SECTION .rodata\n";
  32. }
  33. void WriteFooter(TStringBuf constname) {
  34. AsmOut << AsmPrefix << constname << "Size:\n";
  35. AsmOut << "dd " << AsmPrefix << constname << ".end - " << AsmPrefix << constname << "\n";
  36. }
  37. void WriteSymbolSize(TStringBuf constname) {
  38. AsmOut << "%ifidn __OUTPUT_FORMAT__,elf64\n";
  39. AsmOut << "size " << AsmPrefix << constname << " " << AsmPrefix << constname << ".end - " << AsmPrefix << constname << "\n";
  40. AsmOut << "size " << AsmPrefix << constname << "Size 4\n";
  41. AsmOut << "%endif\n";
  42. }
  43. void WriteIncBin(TStringBuf constname, TStringBuf filename, const TString& data) {
  44. AsmOut << AsmPrefix << constname << ":\nincbin \"" << Basename(filename) << "\"\n";
  45. AsmOut << ".end:\n";
  46. TFixedBufferFileOutput out(filename.data());
  47. out << data;
  48. }
  49. void WriteRaw(TStringBuf constname, const TString& data) {
  50. AsmOut << AsmPrefix << constname << ":\ndb ";
  51. for (size_t i = 0; i < data.size() - 1; i++) {
  52. unsigned char c = static_cast<unsigned char>(data[i]);
  53. AsmOut << IntToString<10, unsigned char>(c) << ",";
  54. }
  55. AsmOut << IntToString<10, unsigned char>(static_cast<unsigned char>(data[data.size() - 1])) << "\n";
  56. AsmOut << ".end:\n";
  57. }
  58. TString Basename(TStringBuf origin) {
  59. TString result(origin);
  60. if (result.rfind('/') != TString::npos) {
  61. result = result.substr(result.rfind('/') + 1);
  62. } else if (result.rfind('\\') != TString::npos) {
  63. result = result.substr(result.rfind('\\') + 1);
  64. }
  65. return result;
  66. }
  67. };
  68. static TString CompressPath(const TVector<TStringBuf>& replacements, TStringBuf in) {
  69. for (auto r : replacements) {
  70. TStringBuf from, to;
  71. r.Split('=', from, to);
  72. if (in.StartsWith(from)) {
  73. return Compress(TString(to) + in.SubStr(from.size()));
  74. }
  75. }
  76. return Compress(in);
  77. }
  78. int main(int argc, char** argv) {
  79. int ind = 0;
  80. if (argc < 4) {
  81. Cerr << "usage: " << argv[ind] << "asm_output --prefix? [-? origin_resource ro_resource]+" << Endl;
  82. return 1;
  83. }
  84. TVector<TStringBuf> replacements;
  85. ind++;
  86. if (TStringBuf(argv[ind]) == "--compress-only") {
  87. ind++;
  88. while (ind + 1 < argc) {
  89. TUnbufferedFileInput inp(argv[ind]);
  90. TString data = inp.ReadAll();
  91. TString compressed = Compress(TStringBuf(data.data(), data.size()));
  92. TFixedBufferFileOutput out(argv[ind+1]);
  93. out << compressed;
  94. ind += 2;
  95. }
  96. return 0;
  97. }
  98. TFixedBufferFileOutput asmout(argv[ind]);
  99. ind++;
  100. TString prefix;
  101. if (TStringBuf(argv[ind]) == "--prefix") {
  102. prefix = "_";
  103. ind++;
  104. }
  105. else {
  106. prefix = "";
  107. }
  108. while (TStringBuf(argv[ind]).StartsWith("--replace=")) {
  109. replacements.push_back(TStringBuf(argv[ind]).SubStr(TStringBuf("--replace=").size()));
  110. ind++;
  111. }
  112. TAsmWriter aw(asmout, prefix);
  113. bool raw;
  114. bool error = false;
  115. while (ind < argc) {
  116. TString compressed;
  117. if ("-"sv == argv[ind]) {
  118. ind++;
  119. if (ind >= argc) {
  120. error = true;
  121. break;
  122. }
  123. compressed = CompressPath(replacements, TStringBuf(argv[ind]));
  124. raw = true;
  125. }
  126. else {
  127. TUnbufferedFileInput inp(argv[ind]);
  128. TString data = inp.ReadAll();
  129. compressed = Compress(TStringBuf(data.data(), data.size()));
  130. raw = false;
  131. }
  132. ind++;
  133. if (ind >= argc) {
  134. error = true;
  135. break;
  136. }
  137. aw.Write(argv[ind], compressed, raw);
  138. ind++;
  139. }
  140. if (error) {
  141. Cerr << "Incorrect number of parameters at argument " << ind - 1 << argv[ind-1] << Endl;
  142. return 1;
  143. }
  144. return 0;
  145. }