main.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  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. TFixedBufferFileOutput asmout(argv[ind]);
  87. ind++;
  88. TString prefix;
  89. if (TStringBuf(argv[ind]) == "--prefix") {
  90. prefix = "_";
  91. ind++;
  92. }
  93. else {
  94. prefix = "";
  95. }
  96. while (TStringBuf(argv[ind]).StartsWith("--replace=")) {
  97. replacements.push_back(TStringBuf(argv[ind]).SubStr(TStringBuf("--replace=").Size()));
  98. ind++;
  99. }
  100. TAsmWriter aw(asmout, prefix);
  101. bool raw;
  102. bool error = false;
  103. while (ind < argc) {
  104. TString compressed;
  105. if ("-"sv == argv[ind]) {
  106. ind++;
  107. if (ind >= argc) {
  108. error = true;
  109. break;
  110. }
  111. compressed = CompressPath(replacements, TStringBuf(argv[ind]));
  112. raw = true;
  113. }
  114. else {
  115. TUnbufferedFileInput inp(argv[ind]);
  116. TString data = inp.ReadAll();
  117. compressed = Compress(TStringBuf(data.data(), data.size()));
  118. raw = false;
  119. }
  120. ind++;
  121. if (ind >= argc) {
  122. error = true;
  123. break;
  124. }
  125. aw.Write(argv[ind], compressed, raw);
  126. ind++;
  127. }
  128. if (error) {
  129. Cerr << "Incorrect number of parameters at argument " << ind - 1 << argv[ind-1] << Endl;
  130. return 1;
  131. }
  132. return 0;
  133. }